using System.Text;
using Gateway.IQuery;
using Gateway.IQuery.Department;
using Gateway.IQuery.Department.Request;
using Gateway.IQuery.Department.Result;
using Gateway.IRepositories;
using Gateway.SqlSugar;

namespace Gateway.Query;

/// <summary>
/// 
/// </summary>
public class DepartmentQuery : IDepartmentQuery
{
    private readonly IQueryRepository _queryRepository;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="queryRepository"></param>
    public DepartmentQuery(IQueryRepository queryRepository)
    {
        _queryRepository = queryRepository;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task<DepartmentDetailResult> GetDetail(string id)
    {
        return await _queryRepository.QueryFirstOrDefaultAsync<DepartmentDetailResult>(
            "select * from Department where Deleted='N' and DepartmentId=@id", new { id });
    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    public async Task<List<DepartmentTreeResult>> GetTree(DepartmentTreeRequest request)
    {
        var allDepartment = await GetAll();
        if ((request?.Action ?? "").Equals("ava"))
        {
            allDepartment = allDepartment.Where(p => p.Disabled.Equals("N")).ToList();
        }

        var rootList = allDepartment.Where(p => string.IsNullOrWhiteSpace(p.ParentId)).OrderBy(p => p.SeqNo).ToList();
        List<DepartmentTreeResult> result = new List<DepartmentTreeResult>();
        foreach (var item in rootList)
        {
            var data = GetAggregateRoot(item, allDepartment);
            result.AddRange(data);
        }

        return result;
    }

    /// <summary>
    /// 递归组织结构
    /// </summary>
    /// <param name="root"></param>
    /// <param name="list"></param>
    /// <returns></returns>
    private List<DepartmentTreeResult> GetAggregateRoot(DepartmentDetailResult root, List<DepartmentDetailResult> list)
    {
        List<DepartmentTreeResult> result = new List<DepartmentTreeResult>();
        var rootModel = new DepartmentTreeResult()
        {
            DepartmentId = root.DepartmentId,
            DepartName = root.DepartName,
            DepartmentCode = root.DepartmentCode,
            SeqNo = root.SeqNo,
            ParentId = root.ParentId,
            Disabled = root.Disabled,
            CreatedTime = root.CreatedTime,
            Remark = root.Remark
        };
        rootModel.Children = new List<DepartmentTreeResult>();
        string id = root.DepartmentId;
        if (!string.IsNullOrWhiteSpace(id))
        {
            var child = list.Where(p => (p.ParentId ?? "").Equals(id)).OrderBy(p => p.SeqNo).ToList();
            if (child.Count > 0)
            {
                foreach (var item in child)
                {
                    var tmpList = GetAggregateRoot(item, list);
                    rootModel.Children.AddRange(tmpList);
                }
            }
        }

        result.Add(rootModel);
        return result.OrderBy(p => p.SeqNo).ToList();
    }

    /// <summary>
    /// 获取所有有效数据
    /// </summary>
    /// <returns></returns>
    public async Task<List<DepartmentDetailResult>> GetAll()
    {
        var data = await _queryRepository.QueryAsync<DepartmentDetailResult>(
            "select  * from  Department where Deleted='N'  ");
        return data.ToList();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    public async Task<PageResult<DepartmentDetailResult>> GetPageList(DepartmentPageListRequest request)
    {
        StringBuilder where = new StringBuilder(100);
        SugarParameters parameters = new SugarParameters();
        if (!string.IsNullOrEmpty(request.DepartmentName))
        {
            where.Append(" AND p.DepartmentName like @DepartmentName");
            parameters.Add("@DepartmentName", $"%{request.DepartmentName}%");
        }

        int count = 0;
        if (request.Page == 1)
        {
            count = await _queryRepository.QueryFirstOrDefaultAsync<int>(
                $@"select count(1) from  Department p where Deleted='N' {where.ToString()}", parameters);
        }

        string sql =
            $@"select departmentid, departmentcode, departname, parentid, remark, seqno, createdtime, lastmodifiedtime, disabled from  Department p where Deleted='N'
{where.ToString()}
order by  DepartmentId,CreatedTime
limit  {request.Offset},{request.PageSize}";
        var data = await _queryRepository.QueryAsync<DepartmentDetailResult>(sql, parameters);
        return PageResult<DepartmentDetailResult>.Create(data.ToList(), count);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parentId"></param>
    /// <returns></returns>
    public async Task<List<string>> GetDepartmentIdListByParentId(string parentId)
    {
        string levelCode = await _queryRepository.QueryFirstOrDefaultAsync<string>(
            "select levelCode from  Department where Deleted='N' and Disabled='N' and DepartmentId=@id",
            new { id = parentId });
        if (string.IsNullOrWhiteSpace(levelCode))
            return new List<string>() { parentId };
        var ids = await _queryRepository.QueryListAsync<string>(
            "select DepartmentId from  Department where Deleted='N' and Disabled='N' and levelCode like @code ",
            new { code = levelCode + "%" });
        if (ids.Count <= 0)
            return new List<string>() { parentId };
        return ids;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parentIdLevelCode"></param>
    /// <returns></returns>
    public async Task<List<string>> GetDepartmentIdListByParentLevelCode(string parentIdLevelCode)
    {
        var ids = await _queryRepository.QueryListAsync<string>(
            "select DepartmentId from  Department where Deleted='N' and Disabled='N' and levelCode like @code",
            new { code = parentIdLevelCode + "%" });
        if (ids.Count <= 0)
            return new List<string>() { };
        return ids;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    public async Task<List<DepartmentDetailResult>> GetDetailByIds(List<string> ids)
    {
        var list = await _queryRepository.QueryListAsync<DepartmentDetailResult>(
            $"select * from  Department where Deleted='N' and DepartmentId in ({string.Join(",", ids.Select(p => $"'{p}'"))})");
        if (list.Count <= 0)
            return new List<DepartmentDetailResult>();
        return list;
    }
}